package com.glp.work.flow.service.impl;

import com.glp.common.reponse.BaseResult;
import com.glp.work.flow.constant.APICode;
import com.glp.work.flow.dto.UserDTO;
import com.glp.work.flow.exception.APIException;
import com.glp.work.flow.mapper.WfBatchMapper;
import com.glp.work.flow.mapper.WfBatchOrderMapper;
import com.glp.work.flow.mapper.WfOrderMapper;
import com.glp.work.flow.mapper.WfTaskAssignMapper;
import com.glp.work.flow.pojo.WfBatch;
import com.glp.work.flow.pojo.WfBatchOrder;
import com.glp.work.flow.pojo.WfOrder;
import com.glp.work.flow.pojo.WfTaskAssign;
import com.glp.work.flow.request.BatchOrder;
import com.glp.work.flow.request.OrderBatchApprovalDTO;
import com.glp.work.flow.response.WfOrderResultDTO;
import com.glp.work.flow.service.UserService;
import com.glp.work.flow.service.WfBatchService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author : 郭永伟
 * @date : 2020/09/08/18:24
 * @description :批次号
 */
@Slf4j
@Service
public class WfBatchServiceImpl implements WfBatchService {

    @Resource
    private WfBatchMapper wfBatchMapper;

    @Resource
    private WfBatchOrderMapper wfBatchOrderMapper;
    @Resource
    private UserService userService;

    @Autowired
    private WfOrderMapper wfOrderMapper;
    @Resource
    TaskService taskService;

    @Resource
    private WfTaskAssignMapper wfTaskAssignMapper;


    @Override
    public String addWfBatch(OrderBatchApprovalDTO orderBatchApprovalDTO) {
        String s = UUID.randomUUID().toString().substring(0, 32);
        if (!CollectionUtils.isEmpty(orderBatchApprovalDTO.getWfOrderResultDTOS())) {
            Set<String> strings = new HashSet<>();
            orderBatchApprovalDTO.getWfOrderResultDTOS().forEach(wfOrderResult -> {
                //验证节点是否正确
                Example example1 = new Example(WfOrder.class);
                example1.createCriteria().andEqualTo("processId", wfOrderResult.getProcessId());
                WfOrder wfOrder = wfOrderMapper.selectOneByExample(example1);
                if (!wfOrder.getCurrentNode().equals(wfOrderResult.getCurrentNode())) {
                    throw new APIException(APICode.DATA_ERROR, "当前工单已被审批！！！" + wfOrderResult.getOrderId());
                }
                if (!StringUtils.isEmpty(wfOrder.getCreateUser())) {
                    strings.add(wfOrder.getCreateUser());
                }
                WfBatchOrder wfBatchOrder = new WfBatchOrder();
                wfBatchOrder.setBatchNo(s);
                wfBatchOrder.setProcessId(wfOrderResult.getProcessId());
                wfBatchOrder.setTaskId(wfOrderResult.getTaskId());
                wfBatchOrderMapper.insertSelective(wfBatchOrder);
            });
            WfOrderResultDTO wfOrderResultDTO = orderBatchApprovalDTO.getWfOrderResultDTOS().get(0);
            WfBatch wfBatch = new WfBatch();
            wfBatch.setBatchNo(s);
            wfBatch.setCreateUser(orderBatchApprovalDTO.getUserNo());
            wfBatch.setProcDefKey(wfOrderResultDTO.getProcDefKey());
            wfBatch.setAppId(wfOrderResultDTO.getAppId());
            wfBatch.setCurrentNode(wfOrderResultDTO.getCurrentNode());
            wfBatch.setStartTime(new Date());
            wfBatch.setOrderNumber(orderBatchApprovalDTO.getWfOrderResultDTOS().size());
            wfBatch.setUserNumber(strings.size());
            wfBatchMapper.insertSelective(wfBatch);
        }
        return s;
    }

    @Override
    public BatchOrder getBatchOrder(List<String> processesIds, String userNo) {
        BatchOrder batchOrder = new BatchOrder();
        List<WfOrderResultDTO> orderResultDTOS = new ArrayList<>();
        Set<Object> set = new HashSet<>();
        HashSet<String> procDefKeys = new HashSet<>();
        HashSet<String> currentNodes = new HashSet<>();

        for (String processesId : processesIds) {
            WfOrderResultDTO wfOrderResultDTO = wfBatchOrderMapper.getBatchOrder(processesId);
            if (wfOrderResultDTO != null) {
                orderResultDTOS.add(wfOrderResultDTO);
                batchOrder.setProcDefName(wfOrderResultDTO.getProcDefName());
                if (wfOrderResultDTO.getCreateUser() != null && !"".equals(wfOrderResultDTO.getCreateUser())) {
                    set.add(wfOrderResultDTO.getCreateUser());
                }
                procDefKeys.add(wfOrderResultDTO.getProcDefKey());
                currentNodes.add(wfOrderResultDTO.getCurrentNode());
            }
        }

        if (procDefKeys.size() > 1) {
            throw new APIException(APICode.DATA_ERROR, "不在同一流程下无法进行批量审批！");
        } else {
            if (currentNodes.size() > 1) {
                throw new APIException(APICode.DATA_ERROR, "不在同一节点下无法进行批量审批！");
            }
        }
        List<Task> list = taskService.createTaskQuery().processInstanceId(processesIds.get(0)).list();
        if (!CollectionUtils.isEmpty(list)) {
            Task task = list.get(0);
            WfTaskAssign wfTaskAssign = new WfTaskAssign();
            wfTaskAssign.setTaskDefId(task.getTaskDefinitionKey());
            wfTaskAssign.setProcDefId(task.getProcessDefinitionId());
            wfTaskAssign = wfTaskAssignMapper.selectOne(wfTaskAssign);
            batchOrder.setSms(wfTaskAssign.getSms());
        }

        BaseResult<UserDTO> personInfo = userService.getPersonInfo(userNo);
        if (personInfo != null && personInfo.getData() != null) {
            UserDTO data = personInfo.getData();
            batchOrder.setUserName(data.getName());
        }
        batchOrder.setOrderNumber(processesIds.size());
        batchOrder.setUserNumber(set.size());
        batchOrder.setOrderResultDTOS(orderResultDTOS);
        return batchOrder;
    }

    @Override
    public WfBatchOrder getWfBatchOrder(String taskId) {
        Example example = new Example(WfBatchOrder.class);
        example.createCriteria().andEqualTo("taskId", taskId);
        return wfBatchOrderMapper.selectOneByExample(example);
    }
}
